import 'dart:async';
import 'dart:io';
import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:nyh_motorcade_app/config/config.dart';
import 'package:nyh_motorcade_app/constant/constant.dart';
import 'package:nyh_motorcade_app/entity/check_version_entity.dart';
import 'package:nyh_motorcade_app/entity/company_entity.dart';
import 'package:nyh_motorcade_app/entity/company_info_entity.dart';
import 'package:nyh_motorcade_app/entity/main_menu_entity.dart';
import 'package:nyh_motorcade_app/entity/unread_message_count_entity.dart';
import 'package:nyh_motorcade_app/event/refresh_home_page_event.dart';
import 'package:nyh_motorcade_app/event/refresh_my_page_event.dart';
import 'package:nyh_motorcade_app/http/http_address.dart';
import 'package:nyh_motorcade_app/http/http_manager.dart';
import 'package:nyh_motorcade_app/routes/routes.dart';
import 'package:nyh_motorcade_app/styles/colors.dart';
import 'package:nyh_motorcade_app/utils/event_bus_utils.dart';
import 'package:nyh_motorcade_app/utils/sp_utils.dart';
import 'package:nyh_motorcade_app/utils/system_utils.dart';
import 'package:nyh_motorcade_app/utils/toast_utils.dart';
import 'package:nyh_motorcade_app/widgets/multi_state/multi_state_widget.dart';
import 'package:nyh_motorcade_app/widgets/update_app_dialog.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';

class HomeController extends GetxController {
  RefreshController refreshController = RefreshController();
  MultiState multiState = MultiState.loading;
  List<CompanyEntity> companyList = [];
  String companyId = "";
  String companyName = "";
  double companyAmount = 0.0;
  double totalAmount = 0.0;
  CompanyInfoEntity? companyInfoEntity;
  List<CompanyInfoAmountDetail> amountDetailList = [];
  double currentMonthAmount = 0.0;
  double currentMonthOrderQuantity = 0.0;
  bool isAdmin = false;
  bool isShowAmountWidget = true;
  bool isShowAmount = true;
  List<MainMenu> mainMenuList = [];
  int unreadMessageCount = 0;
  late StreamSubscription event;

  @override
  void onInit() {
    super.onInit();
    initEvent();
  }

  @override
  Future<void> onReady() async {
    super.onReady();
    companyList = Get.arguments ?? [];
    companyId = await SPUtils.getString(SPUtils.COMPANY_ID);
    getData();
    checkNewVersion();
  }

  @override
  void onClose() {
    super.onClose();
    event.cancel();
  }

  void initEvent() {
    event = EventBusUtils.on<RefreshHomePageEvent>((event) {
      getData();
    });
  }

  Future<void> onRefresh() async {
    getData();
  }

  void onRetry() {
    multiState = MultiState.loading;
    update();
    getData();
  }

  void changeShowAmount() {
    isShowAmount = !isShowAmount;
    update();
  }

  Future<void> changeCompany() async {
    if (companyList.length <= 1) {
      return;
    }
    dynamic data = await Get.toNamed(Routes.changeCompany);
    if (data != null && data is Map) {
      String id = data[Constant.PARAM_COMPANY_ID];
      if (companyId != id) {
        companyId = id;
        multiState = MultiState.loading;
        update();
        getData();
        EventBusUtils.fire(RefreshMyPageEvent());
      }
    }
  }

  Future<void> onAmountClick(int index) async {
    if (isAdmin) {
      String type = amountDetailList[index].type ?? "";
      switch (type) {
        case "COMPANY":
          if (companyInfoEntity != null) {
            dynamic data = await Get.toNamed(Routes.companyManage);
            if (data != null) {
              multiState = MultiState.loading;
              update();
              getData();
            }
          }
          break;
        case "MOTORCADE":
          Get.toNamed(Routes.motorcadeAccount, arguments: companyId);
          break;
        case "CARD":
          Get.toNamed(Routes.cardManage, arguments: false);
          break;
        default:
      }
    } else {
      Get.toNamed(Routes.motorcadeAccount, arguments: companyId);
    }
  }

  Future<void> getData() async {
    if (companyId.isEmpty) {
      ToastUtils.toast("您没有用油客户权限,请联系管理员");
      multiState = MultiState.fail;
      if (refreshController.isRefresh) {
        refreshController.refreshFailed();
      }
      update();
      return;
    }
    Future.wait<dynamic>([getCompanyInfo(), getMainMenu(), getUnreadMessageCount()]).then((value) {
      HttpResult companyHttpResult = value[0];
      HttpResult mainMenuResult = value[1];
      HttpResult unreadMessageCountResult = value[2];
      if (companyHttpResult.data != null && mainMenuResult.data != null) {
        if (refreshController.isRefresh) {
          refreshController.refreshCompleted();
        }
        multiState = MultiState.success;
        handlerCompanyInfo(companyHttpResult.data);
        handlerMainMenu(mainMenuResult.data);
        handlerUnreadMessageCount(unreadMessageCountResult.data);
      } else {
        if (refreshController.isRefresh) {
          refreshController.refreshFailed();
        }
        if (companyHttpResult.state == MultiState.error && mainMenuResult.state == MultiState.error) {
          multiState = MultiState.error;
        } else {
          multiState = MultiState.fail;
        }
      }
      update();
    });
  }

  getCompanyInfo() {
    return httpManager.post(Get.context, HttpAddress.GET_COMPANY_INFO, {"superId": companyId}, isToast: true);
  }

  getMainMenu() {
    return httpManager.post(Get.context, HttpAddress.GET_MAIN_MENU, {}, isToast: true);
  }

  getUnreadMessageCount() {
    return httpManager.post(Get.context, HttpAddress.GET_UNREAD_MESSAGE_COUNT, {"companyId": companyId}, isToast: false);
  }

  void handlerCompanyInfo(data) {
    companyInfoEntity = CompanyInfoEntity().fromJson(data);
    isAdmin = companyInfoEntity!.isAdmin ?? false;
    isShowAmountWidget = (companyInfoEntity!.settlementMethod ?? "") == "PREPAID";
    companyName = companyInfoEntity!.name ?? "";
    totalAmount = companyInfoEntity!.totalAmount ?? 0.0;
    amountDetailList = companyInfoEntity!.amountDetail ?? [];
    currentMonthAmount = companyInfoEntity!.currentMonthAmount ?? 0.0;
    currentMonthOrderQuantity = companyInfoEntity!.currentMonthOrderQuantity ?? 0.0;

    saveCompanyInfo();
  }

  void saveCompanyInfo() {
    SPUtils.saveString(SPUtils.COMPANY_ID, companyId);
    SPUtils.saveString(SPUtils.COMPANY_NAME, companyName);
    if (amountDetailList.isNotEmpty) {
      amountDetailList.forEach((element) {
        if ((element.type ?? "") == "COMPANY") {
          companyAmount = element.amount ?? 0.0;
        }
      });
    }
    SPUtils.saveDouble(SPUtils.COMPANY_AMOUNT, companyAmount);
  }

  void handlerMainMenu(data) {
    mainMenuList.clear();
    if (data is List) {
      List<MainMenuEntity> list = data.map((element) {
        return MainMenuEntity().fromJson((element as Map<String, dynamic>));
      }).toList();
      if (list.isNotEmpty) {
        list.sort((a, b) => a.sort!.compareTo(b.sort!));
        list.forEach((element) {
          switch (element.name) {
            case "CompanySettlement":
              mainMenuList.add(MainMenu(name: element.name ?? "", title: element.title ?? "", icon: "images/ic_home_company_settlement.png", color: Colours.color_34c759_70));
              break;
            case "CashFlow":
              mainMenuList.add(MainMenu(name: element.name ?? "", title: element.title ?? "", icon: "images/ic_home_cash_flow.png", color: Colours.color_34c759_70));
              break;
            case "CardManage":
              mainMenuList.add(MainMenu(name: element.name ?? "", title: element.title ?? "", icon: "images/ic_home_card_manage.png", color: Colours.color_32ade6_70));
              break;
            case "ActivateCard":
              mainMenuList.add(MainMenu(name: element.name ?? "", title: element.title ?? "", icon: "images/ic_home_activate_card.png", color: Colours.color_ff3b30_70));
              break;
            case "RapidTransfer":
              mainMenuList.add(MainMenu(name: element.name ?? "", title: element.title ?? "", icon: "images/ic_home_rapid_transfer.png", color: Colours.color_ff3b30_70));
              handlerTransferPermission(element.childButton ?? []);
              break;
            case "DriverManage":
              mainMenuList.add(MainMenu(name: element.name ?? "", title: element.title ?? "", icon: "images/ic_home_driver_manage.png", color: Colours.color_32ade6_70));
              break;
            case "ImportDriver":
              mainMenuList.add(MainMenu(name: element.name ?? "", title: element.title ?? "", icon: "images/ic_home_input_driver.png", color: Colours.color_ff3b30_70));
              break;
            // case "DriverCode":
            //   mainMenuList.add(MainMenu(name: element.name ?? "", title: element.title ?? "", icon: "images/ic_home_driver_code.png", color: Colours.color_5856d6_70));
            //   break;
            case "CompanyManage":
              mainMenuList.add(MainMenu(name: element.name ?? "", title: element.title ?? "", icon: "images/ic_home_company_manage.png", color: Colours.color_32ade6_70));
              break;
            case "VehicleManage":
              mainMenuList.add(MainMenu(name: element.name ?? "", title: element.title ?? "", icon: "images/ic_home_vehicle_manage.png", color: Colours.color_32ade6_70));
              break;
            case "MessageRemind":
              mainMenuList.add(MainMenu(name: element.name ?? "", title: element.title ?? "", icon: "images/ic_home_message_notify.png", color: Colours.color_ff3b30_70));
              break;
            default:
          }
        });
      }
    }
  }

  void handlerTransferPermission(List<MainMenuChildButton> list) {
    bool permissionTransferCompany = false;
    bool permissionTransferMotorcade = false;
    bool permissionTransferCard = false;
    if (list.isNotEmpty) {
      list.forEach((element) {
        switch (element.name ?? "") {
          case "RapidTransferCompany":
            permissionTransferCompany = true;
            break;
          case "RapidTransferMotorcade":
            permissionTransferMotorcade = true;
            break;
          case "RapidTransferCard":
            permissionTransferCard = true;
            break;
          default:
        }
      });
    }
    SPUtils.saveBool(SPUtils.PERMISSION_TRANSFER_COMPANY, permissionTransferCompany);
    SPUtils.saveBool(SPUtils.PERMISSION_TRANSFER_MOTORCADE, permissionTransferMotorcade);
    SPUtils.saveBool(SPUtils.PERMISSION_TRANSFER_CARD, permissionTransferCard);
  }

  void onMenuClick(String menuName) {
    if (companyId.isEmpty || menuName.isEmpty) {
      return;
    }
    switch (menuName) {
      case "CompanySettlement":
        Get.toNamed(Routes.companySettlement, arguments: {
          Constant.PARAM_COMPANY_ID: companyId,
          Constant.PARAM_COMPANY_NAME: companyName,
          Constant.PARAM_COMPANY_AMOUNT: companyAmount,
        });
        break;
      case "CashFlow":
        Get.toNamed(Routes.cashFlow);
        break;
      case "CardManage":
        Get.toNamed(Routes.cardManage, arguments: true);
        break;
      case "ActivateCard":
        Get.toNamed(Routes.addCard);
        break;
      case "RapidTransfer":
        Get.toNamed(Routes.rapidTransfer, arguments: {
          Constant.PARAM_RAPID_TRANSFER_FROM: Constant.RAPID_TRANSFER_FROM_OTHER,
        });
        break;
      case "DriverManage":
        Get.toNamed(Routes.driverManage);
        break;
      case "ImportDriver":
        Get.toNamed(Routes.addDriver);
        break;
      case "DriverCode":
        Get.toNamed(Routes.driverCode, arguments: {
          Constant.PARAM_COMPANY_ID: companyId,
          Constant.PARAM_COMPANY_NAME: companyName,
        });
        break;
      case "CompanyManage":
        if (companyInfoEntity != null) {
          Get.toNamed(Routes.companyManage);
        }
        break;
      case "VehicleManage":
        Get.toNamed(Routes.vehicleManage);
        break;
      case "MessageRemind":
        Get.toNamed(Routes.messageRemind, arguments: companyId);
        break;
      default:
    }
  }

  void handlerUnreadMessageCount(data) {
    if (data == null) {
      return;
    }
    UnreadMessageCountEntity unreadMessageCountEntity = UnreadMessageCountEntity().fromJson(data);
    unreadMessageCount = unreadMessageCountEntity.msgCount ?? 0;
    update();
  }

  void checkNewVersion() {
    httpManager.post(
      Get.context,
      HttpAddress.CHECK_NEW_VERSION,
      {
        "appType": Config.systemType,
        "systemPlatform": Platform.isAndroid ? 1 : 2,
      },
      onSuccess: (data) {
        showUpdateDialog(data);
      },
    );
  }

  Future<void> showUpdateDialog(dynamic data) async {
    if (data == null) {
      return;
    }
    CheckVersionEntity entity = CheckVersionEntity().fromJson(data);
    bool verifyVersion = await SystemUtils.verifyVersion(entity.version);
    if (!verifyVersion) {
      return;
    }
    showDialog(
      barrierDismissible: false,
      context: Get.context!,
      builder: (BuildContext context) {
        return WillPopScope(
          child: UpdateAppDialog(
            urlPath: entity.downloadUrl ?? "",
            content: entity.versionDescribed,
            isForceUpdate: entity.forcedUpdateOrNot == 1,
          ),
          onWillPop: () async {
            return !(entity.forcedUpdateOrNot == 1);
          },
        );
      },
    );
  }
}

class MainMenu {
  String name;
  String title;
  String icon;
  Color color;

  MainMenu({required this.name, required this.title, required this.icon, required this.color});
}
